﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AppEvents.JsonModel;
using System.IO;
using System.Threading;
using System.Diagnostics;
using MebApp.Launcher.Model;
using MebAppLib;
using TinyUtil;

namespace MebApp.Launcher
{
    public partial class AppInfomationPanel : UserControl
    {
        System.Timers.Timer t = new System.Timers.Timer(1000);
        public AppJson appInfo { get; private set; }
        public AppInfomationPanel()
        {
            InitializeComponent();
            this.panel1.Hide();
            t.Elapsed += T_Elapsed;
        }

        private void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (this.Disposing || this.IsDisposed)
                return;
            try
            {
                this.Invoke(new Action(() =>
                {
                    this.labelNInstances.Text = AppProcess.GetProcessCount(appInfo.ID.ToString()).ToString();
                }));
            }
            catch { }
        }

        public void SetAppInfo(AppJson info)
        {
            if (info == null)
            {
                this.panel1.Visible = false;
            }
            else
            {
                this.panel1.Visible = true;
            }
            this.labelAppName.Text = info.Name;
            var version = AppInstaller.GetInstalledVersion(info.ID);
            this.buttonStartup.Enabled = true;
            this.linkOpenPath.Visible = true;
            this.linkCreateShortcut.Visible = true;
            if (version == -1)
            {
                if (AppInstaller2.GetAppState(info.ID) == AppState.Installing)
                {
                    this.buttonInstall.Text = "正在安装";
                    this.buttonInstall.Enabled = false;
                    this.buttonStartup.Enabled = false;
                    this.linkOpenPath.Visible = false;
                    this.linkCreateShortcut.Visible = false;
                }
                else
                {
                    this.buttonInstall.Text = "安装";
                    this.buttonInstall.Enabled = true;
                    this.buttonStartup.Enabled = false;
                    this.linkOpenPath.Visible = false;
                    this.linkCreateShortcut.Visible = false;
                }
            }
            else if (info.Version > version)
            {
                this.buttonInstall.Text = "更新";
                this.buttonInstall.Enabled = true;
            }
            else
            {
                this.buttonInstall.Enabled = false;
                this.buttonInstall.Text = "安装";
            }
            this.buttonUninstall.Enabled = version != -1;
            this.appInfo = info;
            LoadAppIco();
        }

        private void LoadAppIco()
        {
            try
            {
                var option = AppInstaller.GetLoadOption(appInfo.ID);
                var ico = AppIconHelper.GetIconByFileName(option.StartupFile);
                if (ico != null)
                {
                    this.pictureBox1.BackgroundImage = ico.ToBitmap();
                    this.pictureBox1.BackgroundImageLayout = ImageLayout.Center;
                }
            }
            catch { }
        }


        private void buttonInstall_Click(object sender, EventArgs e)
        {
            AppRuntime option = null;
            if (AppInstaller.IsAppInstalled(appInfo.ID, appInfo.Version))
            {
                option = AppInstaller.GetLoadOption(appInfo.ID);
            }
            else
            {
                var appJsonFile = LauncherApp.AppClient.DownloadUpdateXml(appInfo.ID, appInfo.Version);
                if (appJsonFile == null)
                {
                    this.MessageBoxShow("下载失败。");
                }
                else
                {
                    string installPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../apps/" + appInfo.ID);
                    string appJsonOld = Path.Combine(installPath, "app.json");
                    if (Directory.Exists(installPath) && File.Exists(appJsonOld))
                    {
                        try
                        {
                            var appJson = JsonFile.Read<AppInfo>(appJsonOld);
                            var startupFile = appJson.StartupFile;
                            var processName = Path.GetFileName(startupFile);
                            var processes = Process.GetProcessesByName(processName);
                            if (processes.Any(x => x.MainModule.FileName.Equals(Path.GetFileName(startupFile), StringComparison.OrdinalIgnoreCase)))
                            {
                                MessageBox.Show("请确认完全退出该应用后再试！");
                                return;
                            }
                            File.Delete(appJsonOld);
                        }
                        catch (IOException ex)
                        {
                            this.MessageBoxShow("安装失败，可能文件正在使用中。\r\n" + ex.Message);
                            return;
                        }
                        catch (Exception ex)
                        {
                            this.MessageBoxShow("安装失败，\r\n" + ex.Message);
                            return;
                        }
                    }
                    if (!Directory.Exists(installPath))
                    {
                        Directory.CreateDirectory(installPath);
                    }
                    File.Move(appJsonFile, Path.Combine(installPath, "app.json"));
                    AppInstaller2.RunInstall(appInfo, LauncherApp.AppClient.UserID, installPath, (info, state) =>
                    {
                        try
                        {
                            this.Invoke(new Action<AppJson>((s) => this.SetAppInfo(s)), appInfo);
                        }
                        catch { }
                    });
                }
            }
            this.SetAppInfo(appInfo);
        }

        internal void RunApp()
        {
            if (buttonStartup.Enabled)
                buttonStartup_Click(null, null);
        }

        private void buttonStartup_Click(object sender, EventArgs e)
        {
            var version = AppInstaller.GetInstalledVersion(appInfo.ID);
            var app = LauncherApp.AppClient.GetNewVersion(appInfo.ID, version);
            if (app != null)
            {
                this.SetAppInfo(app);
                if (this.MessageBoxShow("检测到该应用新版已发布，是否继续启动旧版？", MessageBoxButtons.YesNo) == DialogResult.No)
                    return;
            }
            var option = AppInstaller.GetLoadOption(appInfo.ID);
            if (option == null)
            {
                this.MessageBoxShow("无法启动应用，因为没有找到应用运行时选项");
                return;
            }
            option.InstanceID = "shared";
            option.UserID = LauncherApp.AppClient.UserID;
            try
            {
                option.SessionID = DateTime.Now.ToString("HH:mm:ss");
                using (var handle = TinyUtil.SharedMemroy.SetData(option.AppID, option))
                {
                    var startupInfo = new ProcessStartInfo(option.StartupFile, option.StartupArguments);
                    startupInfo.WorkingDirectory = option.StartupPath;
                    var process = Process.Start(startupInfo);
                    process.WaitForExit(3000);
                }
            }
            catch (Exception ex)
            {
                this.MessageBoxShow("启动应用失败, " + ex.Message);
            }
        }

        internal void SetUserApp(UserApp userApp)
        {
            if (userApp == null)
            {
                t.Stop();
                this.labelInstallTime.Text = "N/A";
                this.labelLastRunTime.Text = "N/A";
                this.labelRunTimes.Text = "N/A";
                this.labelNInstances.Text = "N/A";
            }
            else
            {
                t.Start();
                this.labelInstallTime.Text = userApp.CreateTime.ToString();
                this.labelLastRunTime.Text = userApp.LastRunTime.HasValue ? userApp.LastRunTime.ToString() : "N/A";
                this.labelRunTimes.Text = userApp.NAppRuns.ToString();
            }
        }

        private void buttonUninstall_Click(object sender, EventArgs e)
        {
            if (this.MessageBoxShow($"你确定要卸载{appInfo.Name}吗？", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {
                if (AppProcess.GetProcessCount(appInfo.ID.ToString()) > 0)
                {
                    this.MessageBoxShow("请关闭正在运行的实例，然后再尝试卸载！");
                    return;
                }
                AppInstaller.RemoveFromAppList(appInfo.ID);
                LauncherApp.AppClient.RemoveAppInstall(appInfo.ID);
                this.MessageBoxShow("应用卸载完成");
                this.SetAppInfo(appInfo);
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            var option = AppInstaller.GetInstalledApp(appInfo.ID);
            if (option != null)
            {
                Process.Start(option.Location);
            }
        }

        //提交建议
        private void button5_Click(object sender, EventArgs e)
        {
            MessageBox.Show("呵呵，还不是时候~", "提示");
        }
        //反馈问题
        private void button6_Click(object sender, EventArgs e)
        {
            MessageBox.Show("呵呵，还不是时候~", "提示");
        }

        //清除数据
        private void buttonCleanAppData_Click(object sender, EventArgs e)
        {
            MessageBox.Show("抱歉，该特性尚未开放", "提示");
        }


        //创建桌面快捷方式
        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (this.appInfo != null)
            {
                var app = AppInstaller.GetInstalledApp(this.appInfo.ID);
                if (app != null && app.RtmOption != null)
                {
                    Helpers.ShortcutHelper.AddShortcut(this.appInfo.ID, this.appInfo.Name, app.RtmOption.StartupFile);
                }
            }
        }
    }
}
